SWFastLine.c contains several functions for drawing 8-bit lines very quickly (much faster than QuickDraw). All of the functions except SWDrawLine68kAsm clip the line if necessary, and some functions will even draw lines in a scrolling world. Yet others will copy a line from one Frame into another, which can be used to erase lines drawn in the work area the previous frame of the animation. Routines are also provided to draw and copy framed rectangles in both scrolling and non-scrolling SpriteWorlds.
These routines can be used for a variety of purposes. For instance, you could use SWDrawFrameRectInScrollingWorld to draw a rectangle around a Sprite, resulting in an effect similar to WarCraft when you click on units to select them. You could use SWCopyFrameRectInScrollingWorld to erase that rectangle the next frame of the animation, and then call SWDrawFrameRectInScrollingWorld again to draw it in its new position. You might call SWDrawFrameRectInScrollingWorld from the Sprite's DrawProc, or you might install a postEraseCallBack or postDrawCallBack to draw your lines and rects offscreen, as well as erase them from the previous frame.
You can also use these routines for special effects. You could use the SWCopyLine routine creatively to copy your work area to the screen when a level starts, instead of passing true to SWUpdateSpriteWorld.
To use the functions in SWFastLine.c, simply add it to your project (it's in the Utils folder), and don't forget to #include <SWFastLine.h> in your source code too.
Handling Idle Sprites
If you use any of these routines to draw a line or rectangle in the work area of your SpriteWorld, it is possible that you could draw over an idle sprite. This is especially noticeable if you erase your line the next frame, since this leaves a "hole" in the idle sprite where the line used to be. The only solution to this problem is to not use any idle sprites. If necessary, you can set each Sprite's needsToBeDrawn flag to true when its moveProc is called.
Function Parameters
All of the functions contain the following parameters. Here is their description:
dstFrameP - the Frame you want the line drawn in. Can be your SpriteWorld's windowFrameP, workFrameP, or backFrameP, or even a Sprite's FramePtr.
srcPoint and dstPoint - the beginning and end of the line
color - a value between 0 and 255 indicating the color index of the line. If you use the system palette, 0 will be white and 255 will be black, and every value in between is a different color.
Function Reference
---Non-Scrolling functions---
SWDrawLine68kAsm
SW_FUNC void SWDrawLine68kAsm(
FramePtr dstFrameP,
Point srcPoint,
Point dstPoint,
Byte color)
This is a limited routine written in 68k assembly language that will draw lines faster than SWDrawLine. However, this function will not compile for PPC. It also draws the lines a little differently than SWDrawLine, meaning that if you use this function when compiling for 68k and SWDrawLine when compiling for PPC, your lines will look slightly different depending on whether you're running the 68k or PPC version.
Additionally, this function performs no clipping, so make sure your srcPoint and dstPoint are with the dstFrameP's frameRect! Otherwise, your program will most likely crash.
SWDrawLine
SW_FUNC void SWDrawLine(
FramePtr dstFrameP,
Point srcPoint,
Point dstPoint,
Byte color)
This is a line-drawing function written in C, so it compiles for both 68k and PPC Macs. Clipping is performed if necessary. Not for use in a scrolling world - use SWDrawLineInScrollingWorld instead.
SWCopyLine
SW_FUNC void SWCopyLine(
FramePtr srcFrameP,
FramePtr dstFrameP,
Point srcPoint,
Point dstPoint)
Mainly intended for quickly erasing lines drawn with SWDrawLine, SWCopyLine will copy the pixels of a line from srcFrameP to dstFrameP. Both frames must be the same size for clipping to work properly, since the line is only clipped to the dstFrameP.
This function can be used for other purposes besides erasing lines drawn the previous frame. For instance, you might use it to copy the offscreen area to the screen, revealing each row one line at a time.
SWDrawFrameRect
SW_FUNC void SWDrawFrameRect(
FramePtr dstFrameP,
Rect *dstRect,
Byte color)
Use this function to draw a framed rectangle in a non-scrolling world. It works about like QuickDraw's FrameRect function in that the top and left sides are drawn where you specify, and the right and bottom sides are drawn one pixel to the left or one pixel above that side. This is so that if you pass a rect such as 0,0,640,480, to draw a frame around a 640x480 screen, the bottom and right sides will be drawn where they should be. (Remember that if you have 640 pixels, and the first pixel is column 0, your last pixel will be 539, or 640-1.)
Something to keep in mind is that the line routines to *not* have a similar mechanism. That is, if you draw a line from row and column 0 to row 0, column 640, the last pixel of your line will extend past your screen (on a 640x480 screen, that is), since the line routine will stop after drawing pixel 640, not pixel 639.
This may seem like an unconsistent system, but it's the way QuickDraw works, and I figured these routines should work like QuickDraw.
SWCopyFrameRect
SW_FUNC void SWCopyFrameRect(
FramePtr srcFrameP,
FramePtr dstFrameP,
Rect *dstRectP)
This is typically used to erase a framed rect drawn with SWDrawFrameRect the previous frame. It copies a framed rect from srcFrameP to dstFrameP.
---Scrolling functions---
SWDrawLineInScrollingWorld
SW_FUNC void SWDrawLineInScrollingWorld(
SpriteWorldPtr spriteWorldP,
FramePtr dstFrameP,
Point srcPoint,
Point dstPoint,
Byte color)
This function is the same as SWDrawLine, except that it is for use in a scrolling world. (i.e. you should pass the spriteWorldP->workFrameP or spriteWorldP->backFrameP as the dstFrameP parameter).
SWCopyLineInScrollingWorld
SW_FUNC void SWCopyLineInScrollingWorld(
SpriteWorldPtr spriteWorldP,
FramePtr srcFrameP,
FramePtr dstFrameP,
Point srcPoint,
Point dstPoint,
Rect *clipRectP)
Typically used to erase lines drawn the previous frame with SWDrawLineInScrollingWorld. Generally the srcFrameP would be the spriteWorldP->backFrameP, and the dstFrameP would be the spriteWorldP->workFrameP.
The clipRectP is a new parameter that specifies what rectangle the drawing should be clipped to. You should pass either the spriteWorldP->visScrollRect or spriteWorldP->oldVisScrollRect. Use the oldVisScrollRect if you are erasing a line from the previous frame.
SWDrawFrameRectInScrollingWorld
SW_FUNC void SWDrawFrameRectInScrollingWorld(
SpriteWorldPtr spriteWorldP,
FramePtr dstFrameP,
Rect *dstRectP,
Byte color)
Used to draw framed rectangles in a scrolling world.
SWCopyFrameRectInScrollingWorld
SW_FUNC void SWCopyFrameRectInScrollingWorld(
SpriteWorldPtr spriteWorldP,
FramePtr srcFrameP,
FramePtr dstFrameP,
Rect *dstRectP,
Rect *clipRectP)
Typically used to erase framed rects drawn with SWDrawFrameRectInScrollingWorld the previous frame.
The clipRectP specifies what rectangle the drawing should be clipped to. You should pass either the spriteWorldP->visScrollRect or spriteWorldP->oldVisScrollRect. Use the oldVisScrollRect if you are erasing a line from the previous frame.